#include "command.h"

int handler_puts(int sockfd, data msg, char *name, MYSQL *mysql)
{
    // 文件是否需要上传的标记位，0表示需要上传，1表示不需要上传
    int flag = 0;
    char *p = "/"; // 用于拼接路径
    // 获取文件名
    char file_name_buf[1024] = {0};
    strcpy(file_name_buf, msg.args);

    // 接收客户端工作路径
    char file_path_buf[1024] = {0};
    recv(sockfd, file_path_buf, sizeof(file_name_buf), MSG_WAITALL);
    // 保存一个父路径
    char father_path[1024] = {0};
    strcpy(father_path, file_path_buf);
    // 接收客户端文件的哈希值
    char file_hash_buf[512] = {0};
    recv(sockfd, file_hash_buf, sizeof(file_hash_buf), MSG_WAITALL);

    // 拼接文件路径
    char *p1 = "file";
    char path1[1024] = {0};
    char *path = getcwd(path1, sizeof(path1));
    strcat(path, p);
    strcat(path, p1);
    strcat(path, p);
    strcat(path, file_hash_buf);

    // 从数据库中查询hash值，is-dalate,up_load_status判断要上传的文件是否以及存在
    // 拼接文件路径
    if(!strcmp(father_path,"/")){
        strcat(file_path_buf, file_name_buf);
    }else{
        strcat(file_path_buf, p);
        strcat(file_path_buf, file_name_buf);
    }
    // 构建sql语句
    char sql_buf[1024] = {0};
    snprintf(sql_buf, sizeof(sql_buf), "select file_hash, is_deleted, upload_status from file where user_id =(select user_id from user where user_name = '%.*s' ) and file_path = '%.*s'", 255, name, 255, file_path_buf);

    // 进行查询
    mysql_query(mysql, sql_buf);
    // 获取返回值
    MYSQL_RES *result = mysql_store_result(mysql);
    // 处理查询不到任何东西的逻辑，发送标记位
    if (result == NULL || mysql_num_rows(result) == 0)
    {
        // 查询为空,即服务器没有这个文件
        send(sockfd, &flag, sizeof(int), MSG_NOSIGNAL);
        // 往数据库中插入文件相关信息，同时开始接收上传的文件
        // 拼接sql语句
        char sql_insert[2048] = {0};
        // snprintf(sql_insert, sizeof(sql_insert), "insert into file((file_name, user_id, file_path, file_type, file_hash, is_deleted, father_id) values ('%.*s',(select user_id form user where user_name = '%.*s'),'%.*s',2,'%.*s,0,(select file_id from file where file_path = '%.*s' and user_id = (select user_id form user where user_name = '%.*s'))')");
        snprintf(sql_insert, sizeof(sql_insert),
                 "INSERT INTO file (file_name, user_id, file_path, file_type, file_hash, is_deleted, father_id) "
                 "VALUES ('%.*s', (SELECT user_id FROM user WHERE user_name = '%.*s'), '%.*s', 2, '%.*s', 0, "
                 "(SELECT f.file_id FROM file f WHERE f.file_path = '%.*s' AND f.user_id = (SELECT user_id FROM user WHERE user_name = '%.*s')))",
                 255, file_name_buf, 255, name, 255, file_path_buf, 255, file_hash_buf, 255, father_path, 255, name);

        if (mysql_query(mysql, sql_insert))
        {
            fprintf(stderr, "MySQL Error: %s\n", mysql_error(mysql));
            return -1; // 或者其他错误处理
        }
        // 打开文件
        int file_fd = open(path, O_RDWR | O_CREAT | O_APPEND, 0664);
        // 计算存在的文件大小
        off_t size = lseek(file_fd, 0, SEEK_END);
        // 发送存在的文件大小
        send(sockfd, &size, sizeof(off_t), MSG_NOSIGNAL);
        // 接收文件总大小
        off_t serve_size;
        recv(sockfd, &serve_size, sizeof(off_t), MSG_WAITALL);
        // 接收文件
        // 定义一个变量存储每次读取的数据块
        ssize_t chunk_size = 1024;
        char buf[1024] = {0};
        // 接受剩下的文件
        while (serve_size > size)
        {
            // 每次重置buf,防止不够1024时，buf前半部分时上次的数据
            memset(buf, 0, sizeof(buf));
            // 计算应该读取的字节数
            off_t read_bytes = (serve_size - size) < chunk_size ? (serve_size - size) : chunk_size;
            // 实际读取的字节数
            off_t cur_size = recv(sockfd, buf, read_bytes, MSG_WAITALL);
            if (cur_size == 0)
            {
                printf("端断开连接\n");
                break;
            }
            write(file_fd, buf, cur_size);
            // 累加当前文件以及存在的字节数
            size += cur_size;
            off_t need_size = serve_size - size;
            if (need_size <= 0)
            {
                printf("文件下载完成!\n");
                // 拼接sql语句
                char sql_update[1024] = {0};
                snprintf(sql_update, sizeof(sql_update), "update file set upload_status = 1 where user_id = (select user_id from user where user_name =  '%.*s') and file_path = '%.*s'", 255, name, 255, file_path_buf);
                // 执行sql修改upload_status为1
                mysql_query(mysql, sql_update);
                close(file_fd);
                break;
            }
        }
        return 0;

        // 释放结果集
        mysql_free_result(result);
        return 0;
    }

    // 从返回值中取出结果返回结果存入buf数组中
    char select_buf[1024] = {0};
    MYSQL_ROW row;
    while (row = mysql_fetch_row(result))
    {
        for (int i = 0; i < mysql_num_fields(result); i++)
        {
            strncat(select_buf, row[i], strlen(row[i]));
            strncat(select_buf, "\t", 4);
        }
    }

    // 释放结果集
    mysql_free_result(result);
    // 此时select_buf存放的数据为file_hash \t is_deleted \t upload_status
    // 切割
    char *serve_hash = strtok(select_buf, "\t");
    char *serve_is_deleted = strtok(select_buf, "\t");
    char *serve_upload_status = strtok(select_buf, "\t");
    printf("serve_hash = %s, serve_is_deleted = %s, serve_upload_status = %s\n", serve_hash, serve_is_deleted, serve_upload_status);
    if (!strcmp(serve_is_deleted, "0") && !strcmp(serve_upload_status, "1"))
    {
        // 文件存在于服务端，不需要上传
        int flag = 1;
        send(sockfd, &flag, sizeof(int), MSG_NOSIGNAL);
        return 0;
    }
    else
    {
        // 文件存在但是不完整，需要上传文件
        int flag = 0;
        send(sockfd, &flag, sizeof(int), MSG_NOSIGNAL);
        // 打开文件
        int file_fd = open(path, O_RDWR | O_APPEND);
        // 计算存在的文件大小
        off_t size = lseek(file_fd, 0, SEEK_END);
        // 发送存在的文件大小
        send(sockfd, &size, sizeof(off_t), MSG_NOSIGNAL);
        // 接收文件总大小
        off_t serve_size;
        recv(sockfd, &serve_size, sizeof(off_t), MSG_WAITALL);
        // 接收文件
        // 定义一个变量存储每次读取的数据块
        ssize_t chunk_size = 1024;
        char buf[1024] = {0};
        // 接受剩下的文件
        while (serve_size > size)
        {
            // 每次重置buf,防止不够1024时，buf前半部分时上次的数据
            memset(buf, 0, sizeof(buf));
            // 计算应该读取的字节数
            off_t read_bytes = (serve_size - size) < chunk_size ? (serve_size - size) : chunk_size;
            // 实际读取的字节数
            off_t cur_size = recv(sockfd, buf, read_bytes, MSG_WAITALL);
            if (cur_size == 0)
            {
                printf("端断开连接\n");
                break;
            }
            write(file_fd, buf, cur_size);
            // 累加当前文件以及存在的字节数
            size += cur_size;
            off_t need_size = serve_size - size;
            if (need_size <= 0)
            {
                printf("文件下载完成!\n");
                // 拼接sql语句
                char sql_update[1024] = {0};
                snprintf(sql_update, sizeof(sql_update), "update file set upload_status = 1 where user_id = (select user_id from user where user_name =  '%.*s') and file_path = '%.*s'", 255, name, 255, file_path_buf);
                // 执行sql修改upload_status为1
                mysql_query(mysql, sql_update);
                close(file_fd);
                break;
            }
        }
        return 0;
    }
}